package spring.spring_affairs.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.framework.AopContext;
import org.springframework.aop.framework.AopProxy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import spring.spring_affairs.model.logInfo;
import spring.spring_affairs.model.userInfo;
import spring.spring_affairs.server.logInfoServer;
import spring.spring_affairs.server.userInfoServer;

@Slf4j
@RequestMapping("t")
@RestController
public class userController {

    //获取事务管理器
    @Autowired
    DataSourceTransactionManager transactionManager;
    //获取事务的类型 使用在这个可以设置事务传播类型 而TransactionDefinition不行
    @Autowired
    DefaultTransactionDefinition transactionDefinition;
    @Autowired
    logInfoServer logInfoServer;
    @Autowired
    userInfoServer userInfoServer;

    //使用类的方式来回滚
    @RequestMapping("t1")
    public String t1() {
        userInfo u = new userInfo("wowm", "cool");

        //开启事务
        transactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
        TransactionStatus transaction = transactionManager.getTransaction(transactionDefinition);

        userInfoServer.insertUserInfo(u);
        transactionManager.commit(transaction);//提交
        return "success";
//        log.info("----手动回滚----");
//        transactionManager.rollback(transaction);//提交
//        return "rollback";

    }

    /**
     * 使用注解来设置隔离级别 加入xml依赖
     * 在抛出异常RuntimeException和Error异常之后会自动回滚 如果异常被捕获或者被向外抛出了会正常提交
     * - @Transactional()可以设置事务传播机制propagation和隔离级别isolation
     * - rollbackFor可以设定回滚的事务的异常类型
     */

    @Transactional(propagation = Propagation.REQUIRED)
    @RequestMapping("t2")
    public String t2() throws NullPointerException {
        userInfo u = new userInfo("mmww", "cool");
            userInfoServer.insertUserInfo(u);
        logInfo l = new logInfo("mmcool", "ww");
        logInfoServer.insertLogInfo(l);
        return "success";
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @RequestMapping("t3")
    public String t3() {
        userInfo u = new userInfo("cool", "cool");
        userInfoServer.insertUserInfo(u);
        //回滚
        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        // 你抛出的是空指针异常 这个方法被重写了诶是的，currentTransactionStatus 返回了一个实例 info.transactionStatus
        // 阿塔不会抛出异常的话，我这里回滚了
//        throw new NullPointerException();
        return "success";
    }


    @Transactional(propagation = Propagation.REQUIRED)
    @RequestMapping("t5")
    public String t5() {
        logInfo u = new logInfo("mwowm1", "cool");
        logInfoServer.insertLogInfo(u);
        userController c = (userController) AopContext.currentProxy();
        c.t4();
//        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        return "success";
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    @RequestMapping("t4")
    public String t4() {
        userInfo u = new userInfo("cool1", "cool");
        userInfoServer.insertUserInfo(u);
        //回滚
        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        return "success";
    }


}
